package com.ccteam.fluidmusic.view.adapters

import android.view.ViewGroup
import androidx.recyclerview.widget.DiffUtil
import androidx.recyclerview.widget.ListAdapter
import androidx.recyclerview.widget.RecyclerView
import androidx.viewbinding.ViewBinding
import com.ccteam.fluidmusic.databinding.GlobalEmptyItemBinding

/**
 * @author Xiaoc
 * @since 2021/1/25
 *
 * 基于ViewBinding机制的RecyclerView适配基类
 * 对其中一些内容作了一些封装，基于ListAdapter
 * 自带空布局效果，当List没有内容时就会显示成空布局
 * 你可以重写 [bindEmptyView] 方法对空布局内容进行更改和监听
 *
 * 一般不继承该基类适配器，请使用它的子类，更加方便快捷
 * 对于单个Item的内容：[ViewBindingAdapter]
 * 对于多个Item的内容：[MultiTypeViewBindingAdapter]
 **/
abstract class BaseViewBindingAdapter<VH: RecyclerView.ViewHolder,E>(
    diffItemCallback: DiffUtil.ItemCallback<E>
): ListAdapter<E, VH>(diffItemCallback) {

    /**
     * 创建视图容器
     * 会调用 [createViewBinding] 抽象方法调用用户自己实现的视图容器
     *
     * 一旦出现viewHolder为空的情况，目前的处理是直接抛出异常
     */
    final override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): VH {
        val viewHolder = createViewBinding(parent,viewType)
        return viewHolder ?: throw IllegalArgumentException("无效不支持的布局：$viewType")
    }

    /**
     * 创建视图ViewBinding视图容器，为抽象方法，需要自己实现
     */
    abstract fun createViewBinding(parent: ViewGroup, viewType: Int): VH?

    /**
     * 绑定视图与数据
     */
    final override fun onBindViewHolder(holder: VH, position: Int) {
        onBindViewHolder(holder,position,mutableListOf())
    }

    /**
     * 绑定视图与数据
     * 会调用 [bindItem] 让子类去填充对应布局的内容
     */
    final override fun onBindViewHolder(
        holder: VH,
        position: Int,
        payloads: MutableList<Any>
    ) {
        bindItem(holder,position,getItem(position),payloads)
    }

    /**
     * 绑定对应布局的内容视图，抽象方法需要子类实现
     * @param holder 基于ViewBinding的视图容器
     * @param position 当前绑定的是什么位置的数据和视图
     * @param item 当前绑定的数据
     * @param payloads 局部加载的数据
     */
    abstract fun bindItem(holder: VH,
                          position: Int,
                          item: E,
                          payloads: MutableList<Any>)

}

/**
 * 基于ViewBinding机制的ViewHolder视图容器类
 * 它自行进行了基本处理
 * 你的ViewHolder只需要继承它，然后知道如何创建它就可以了
 * @param V 这是告诉当前ViewHolder存储的是哪个视图类型，它是ViewBinding的子类
 *
 */
abstract class ViewBindViewHolder<V: ViewBinding>(
    val binding: V
): RecyclerView.ViewHolder(binding.root)

/**
 * 空布局的ViewHolder
 * 全局通用
 */
class EmptyViewHolder(
    emptyBinding: GlobalEmptyItemBinding
): ViewBindViewHolder<GlobalEmptyItemBinding>(emptyBinding)

